package com.example.web.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.web.SysConst;
import com.example.web.dto.*;
import com.example.web.dto.query.*;
import com.example.web.entity.*;
import com.example.web.mapper.*;
import com.example.web.service.*;
import com.example.web.tools.Extension;
import com.example.web.tools.JWTUtils;
import com.example.web.tools.dto.PagedResult;
import com.example.web.tools.exception.CustomException;
import lombok.SneakyThrows;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.management.relation.Role;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户功能实现类
 */
@Service
public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> implements AppUserService {


    /**
     * 操作数据库的用户表mapper对象
     */
    @Autowired
    private AppUserMapper _AppUserMpper;


    /**
     * 用户分页查询
     */
    @SneakyThrows
    @Override
    public PagedResult<AppUserDto> List(AppUserPagedInput input) {


        //声明一个支持用户查询的(拉姆达)表达式
        LambdaQueryWrapper<AppUser> queryWrapper = Wrappers.<AppUser>lambdaQuery()
                .eq(input.getId()!=null,AppUser::getId,input.getId())
                .eq(input.getCreatorId()!=null,AppUser::getCreatorId,input.getCreatorId());

        //如果前端搜索传入Name不为空,则进行精确查询
        if(Extension.isNotNullOrEmpty(input.getName())) {
            queryWrapper=queryWrapper.eq(AppUser::getName,input.getName());
        }

        //如果前端搜索传入Email不为空,则进行精确查询
        if(Extension.isNotNullOrEmpty(input.getEmail())) {
            queryWrapper=queryWrapper.eq(AppUser::getEmail,input.getEmail());
        }

        //如果前端搜索传入getPhoneNumber不为空,则进行精确查询
        if(Extension.isNotNullOrEmpty(input.getPhoneNumber())) {
            queryWrapper=queryWrapper.eq(AppUser::getPhoneNumber,input.getPhoneNumber());
        }

        //如果前端搜索传入getRoleType不为空,则进行精确查询
        if(input.getRoleType()!=null) {
            queryWrapper=queryWrapper.eq(AppUser::getRoleType,input.getRoleType());
        }


        //如果前端传入了BirthRange时间范围,则进行时间范围搜索
        if(input.getBirthRange()!=null&&input.getBirthRange().stream().count()>1)
        {
            queryWrapper=queryWrapper.lt(AppUser::getBirth,input.getBirthRange().get(1));
            queryWrapper=queryWrapper.gt(AppUser::getBirth,input.getBirthRange().get(0));
        }


        //按创建时间从大到小排序 最新的显示在最前面
        queryWrapper=queryWrapper.orderByDesc(AppUser::getCreationTime);
        //构建一个分页查询的model
        Page<AppUser> page = new Page<>(input.getPage(), input.getLimit());

        //从数据库进行分页查询获取用户数据
        IPage<AppUser> pageRecords= _AppUserMpper.selectPage(page, queryWrapper);

        //获取所有满足条件的数据行数
        Long totalCount= _AppUserMpper.selectCount(queryWrapper);

        //把用户实体转换成用户传输模型
        List<AppUserDto> items= Extension.copyBeanList(pageRecords.getRecords(),AppUserDto.class);

        //返回一个分页结构给前端
        return PagedResult.GetInstance(items,totalCount);

    }

    /**
     *用户创建或者修改
     */
    @SneakyThrows
    @Override
    public AppUserDto CreateOrEdit(AppUserDto input)  {

        //声明一个用户实体
        AppUser AppUser = new AppUser();

        //把前端传入的input参数拷贝到用户实体
        BeanUtils.copyProperties(AppUser,input);

        //如果前端没有给新密码,则把原始密码继续赋值
        if(Extension.isNotNullOrEmpty(input.getPassword()))
        {
            input.setPassword(input.getOrginPassword());
        }

        //调用数据库的增加或者修改方法
        saveOrUpdate(AppUser);

        //定义一个返回给前端的用户传输模型
        AppUserDto AppUserDto=new AppUserDto();

        //同理把操作的用户实体拷贝给用户传输模型
        BeanUtils.copyProperties(AppUserDto,AppUser);

        //把传输模型返回给前端
        return AppUserDto;
    }

    /**
     * 单个用户查询
     */
    @SneakyThrows
    @Override
    public AppUserDto Get(AppUserPagedInput input) {
        if(input.getId()==null)
        {
            return new AppUserDto();
        }
        PagedResult<AppUserDto>  pagedResult =List(input);
        return pagedResult.getTotalCount()>0?pagedResult.getItems().stream().findFirst().get():new AppUserDto();
    }


    /**
     * 登录
     */
    public String SignIn(AppUserDto input){
        LambdaQueryWrapper<AppUser> queryWrapper = Wrappers.<AppUser>lambdaQuery()
                .eq(Extension.isNotNullOrEmpty(input.getUserName()),AppUser::getUserName,input.getUserName())
                .eq(Extension.isNotNullOrEmpty(input.getPassword()),AppUser::getPassword,input.getPassword())
                .eq(input.getRoleType()!=null,AppUser::getRoleType,input.getRoleType());

        List<AppUser> items=_AppUserMpper.selectList(queryWrapper);
        if(items.stream().count()==0)
        {
            throw  new CustomException("请检查登录的账号或者密码,角色是否都正确!");
        }
        Map<String, String> map = new HashMap<>();
        map.put(SysConst.UserIdClaim,items.get(0).getId().toString());
        map.put(SysConst.RoleTypeClaim,items.get(0).getRoleType().toString());
        String token=JWTUtils.getToken(map);
        return token;
    }
    /**
     * 注册
     */
    @Override
    public AppUserDto Register(AppUserDto input) {
        
        
        LambdaQueryWrapper<AppUser> queryWrapper = Wrappers.<AppUser>lambdaQuery()
                .eq(input.getUserName()!=null,AppUser::getUserName,input.getUserName())
                .eq(input.getPhoneNumber()!=null,AppUser::getPhoneNumber,input.getPhoneNumber());
       //根据用户名称或用户电话号码进行查询
        AppUser appUser = _AppUserMpper.selectOne(queryWrapper);
        if(appUser!=null)
        {
            throw  new CustomException("该用户名或手机号已经存在!");
        }
        return  CreateOrEdit(input);
    }
}
